﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GestorDeFlotasModelo.Factorias;
using GestorDeFlotasModelo.Entities;
using GestorDeFlotasDesktop.UILogic;
using GestorDeFlotasDesktop.UILogic.Helpers;

namespace GestorDeFlotasDesktop
{
    public partial class FormUsuario : BaseForm
    {
        private Int64 CurrentUserId { get; set; }
        private FormMode Mode { get; set; } 

        public FormUsuario()
        {
            InitializeComponent();
        }

        protected override void  OnVisibleChanged(EventArgs e)
        {
            try
            {
                base.OnVisibleChanged(e);
                PrepareForm(this.Mode);
                if (lsRoles.Items.Count <= 0)
                {
                    lsRoles.DisplayMember = "Nombre";
                    lsRoles.ValueMember = "Id";
                    lsRoles.DataSource = Transaccion.Factoria<FactoriaRol>().SelectTodosHabilitados<Rol>();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        #region Private Members
        /// <summary>
        /// Si todas las validaciones son correctas, se crea el nuevo usuario en BD.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddOrUpdate_Click(object sender, EventArgs e)
        {
            try
            {
                if (!ValidateFields())
                {
                    if (Mode == FormMode.Add)
                    {
                        List<Rol> roles = GetSelectedRoles();

                        string password = SecurityHelpers.PasswordHashed(txtPassword.Text);
                        Usuario user = Transaccion.Factoria<FactoriaUsuario>().Nuevo(txtUserName.Text,
                                                                                    password,
                                                                                    true,
                                                                                    0,
                                                                                    roles);
                        Transaccion.Persistir();

                        roles.ForEach(rol => Transaccion.Factoria<FactoriaRolPorUsuario>().Nuevo(rol, user));

                        Transaccion.Persistir();
                    }
                    else
                    {
                        if (CurrentUserId <= 0)
                            lblError.Text += "No hay ningún usuario seleccionado";
                        else
                        {
                            Usuario user = Transaccion.Factoria<FactoriaUsuario>().SelectXId<Usuario>(CurrentUserId.ToString());

                            if (!String.IsNullOrEmpty(txtPassword.Text))
                                user.Password = SecurityHelpers.PasswordHashed(txtPassword.Text);

                            user.Habilitado = chkEnabled.Checked;
                            List<Rol> rolesOriginales = user.Roles;
                            List<Rol> rolesAsignados = GetSelectedRoles();
                            foreach(Rol rol in rolesOriginales)
                                if(!rolesAsignados.Contains(rol))
                                {
                                    RolPorUsuario rolporusuario=Transaccion.Factoria<FactoriaRolPorUsuario>().SelectXId<RolPorUsuario>(user.Id+"|"+rol.Id);
                                    Transaccion.Factoria<FactoriaRolPorUsuario>().Eliminar(rolporusuario);
                                }

                            foreach(Rol rol in rolesAsignados)
                                if (!rolesOriginales.Contains(rol))
                                {
                                    RolPorUsuario rolporusuario = Transaccion.Factoria<FactoriaRolPorUsuario>().SelectXId<RolPorUsuario>(user.Id + "|" + rol.Id);
                                    Transaccion.Factoria<FactoriaRolPorUsuario>().Nuevo(rol, user);
                                }
                            Transaccion.Persistir();
                        }
                    }
                    if (String.IsNullOrEmpty(lblError.Text))
                    {
                        Transaccion.Cerrar();
                        AbmUsuario.AbmUsuario list = new AbmUsuario.AbmUsuario();
                        list.Show();
                        this.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private List<Rol> GetSelectedRoles()
        {
            List<Rol> roles = new List<Rol>();
            foreach (object item in lsRoles.SelectedItems)
            {
                roles.Add((Rol)item);
            }
            return roles;
        }
        private bool ValidateFields()
        {
            bool error = false;
            string errorMessage = string.Empty;

            if (!ValidatorHelper.isStringFieldValid(txtUserName.Text) && Mode== FormMode.Add)
            {
                errorMessage = "No ingresaste el nombre de usuario \n";
                error = true;
            }
            else
            {
                List<Usuario> usuarios = Transaccion.Factoria<FactoriaUsuario>().SelectPorUserName(txtUserName.Text);
                
                if (this.Mode == FormMode.Update) usuarios = usuarios.Where(u => u.Id != this.CurrentUserId).ToList<Usuario>();

                if (usuarios.Count > 0)
                {
                    error = true;
                    errorMessage = "El usuario ingresado ya existe \n";
                }
            }

            if (!ValidatorHelper.isStringFieldValid(txtPassword.Text) && Mode == FormMode.Add)
            {
                errorMessage += "No ingresaste una contraseña \n";
                error = true;
            }

            if (!ValidatorHelper.isListBoxFieldValid(lsRoles))
            {
                errorMessage += "No seleccionaste ningún rol \n";
                error = true;
            }

            lblError.Text = errorMessage;
            lblError.Visible = error;

            return error;
        }

        private void ResetFields()
        {
            txtUserName.Text = txtPassword.Text = lblError.Text = string.Empty;
            lblError.Visible = false;
            txtUserName.ReadOnly = false;
        }

        private void PrepareForm(FormMode mode)
        {
            if (mode == FormMode.Add)
            {
                lblHabilitado.Visible = false;
                chkEnabled.Visible = false;
                btnAddOrUpdate.Text = "Agregar";
            }
            else
            {
                lblHabilitado.Visible = true;
                chkEnabled.Visible = true;
                btnAddOrUpdate.Text = "Modificar";
            }
        }

        private void LoadData(Usuario user)
        {
            Usuario usuarioPosta = Transaccion.Factoria<FactoriaUsuario>().SelectXId<Usuario>(user.Id.ToString());
            txtUserName.Text = usuarioPosta.Username;
            txtUserName.Enabled = false;
            chkEnabled.Checked = usuarioPosta.Habilitado;

            foreach (Rol rol in usuarioPosta.Roles)
            {
                lsRoles.SelectedItems.Add(rol);
            }
        }
        #endregion
        public void LoadForm(FormMode mode, Usuario user)
        {
            
            this.Mode = mode;
            ResetFields();
            //Si hay un usuario, cargo el CurrentUserId y también sus datos en el form.
            if (mode == FormMode.Add) this.CurrentUserId = 0;
            else
            {
                LoadData(user);
                this.CurrentUserId = user.Id;
            }
        }


    }
}